/**
 * @author Ahammer
 * @date   2010 05
 * @update 
 */

/*
 * This file is part of Iqm.
 * Copyright (c) 2010-2011 Helmut Ahammer
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package opgui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import javax.media.jai.ParameterBlockJAI;
import javax.media.jai.PlanarImage;
import javax.media.jai.ROIShape;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JSpinner;
import javax.swing.JToolBar;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.InternationalFormatter;

import main.Board;
import main.IqmTools;
import main.Tank;

public class IqmWatershedGUI  extends IqmOperatorJFrame
						      implements IqmOperatorGUIBuilder, ActionListener, PropertyChangeListener, ChangeListener {

	private  ParameterBlockJAI   pbJAI         = null;  //  @jve:decl-index=0:
	//public  ImgProcFuncJFrame  opGUIFrame = null;
	//private  IqmWatershedGUI   opGUIFrame = null;  //actionPerformed events werden in dieser Klasse abgehandelt
	
	
	private  JCheckBox 	           jCheckBoxInvert	   = null;
	
	private  JRadioButtonMenuItem  buttNone            = null;	
	private  JRadioButtonMenuItem  buttGauss           = null;	
	private  JRadioButtonMenuItem  buttPreProcHidden   = null;
	private  JToolBar              jToolBarPreProc     = null;
	private  ButtonGroup           buttGroupPreProc    = null;
	
	private JPanel 				   jPanelKernel		   = null;	
	private JLabel				   jLabelKernel		   = null;
	private JSpinner 			   jSpinnerKernel      = null;

	private JRadioButtonMenuItem   buttCon4             = null;
	private JRadioButtonMenuItem   buttCon8             = null;	
	private JRadioButtonMenuItem   buttConnectivetyHidden = null;
	private JToolBar               jToolBarConnectivety   = null;
	private ButtonGroup            buttGroupConnectivety  = null;
	private JPanel			       jPanelConnectivety     = null;
	private	JLabel				   jLabelConnectivety	    = null;
	
	private JPanel 				 	jPanelThresMin		= null;	
	private JLabel				 	jLabelThresMin		= null;
	private JFormattedTextField 	jFormattedTextFieldThresMin     = null;	
	private JSpinner			 	jSpinnerThresMin 	= null;
	private JPanel 				 	jPanelThresMax		= null;	
	private JLabel				 	jLabelThresMax		= null;
	private JFormattedTextField 	jFormattedTextFieldThresMax    = null;	
	private JSpinner			 	jSpinnerThresMax 	= null;

	private  JRadioButtonMenuItem  buttDam         = null;	
	private  JRadioButtonMenuItem  buttOverDam     = null;	
	private  JRadioButtonMenuItem  buttColBas      = null;	
	private  JRadioButtonMenuItem  buttComposite   = null;		
	private  JRadioButtonMenuItem  buttOutputHidden   = null;
	private  JToolBar              jToolBarOutput     = null;
	private  ButtonGroup           buttGroupOutput    = null;
	
	/**
	 * constructor
	 */
	public IqmWatershedGUI() {

	}

	
	/**
	 * This method sets all  variables to null
	 */
	private void resetVariables(){
		pbJAI         = null; 
		//opGUIFrame = null; 
		
		//jToolBarRGB  = null;

	}
	/**
	 * This method sets all parameters to null
	 */
	private void resetParameters(){
		//butt       = null;
		//butt       = null;
	}

	/**
	 * This method sets the current parameter block to the argument
	 * @param ParameterBlockJAI pbJAI
	 */
	@Override
	public void setParameterBlock(ParameterBlockJAI arg){
		pbJAI = arg;
		IqmTools.setCurrParameterBlockJAI(pbJAI);	
	}
	/**
	 * This method sets the current parameter block
	 * The individual values of the GUI  current ParameterBlock
	 *
	 */
	@Override
	public void setParameterBlock(){
		if (jCheckBoxInvert.isSelected())    pbJAI.setParameter("Invert", 1);
		if (!jCheckBoxInvert.isSelected())   pbJAI.setParameter("Invert", 0);	
		if (buttNone.isSelected())      pbJAI.setParameter("PreProc", 0);
		if (buttGauss.isSelected())     pbJAI.setParameter("PreProc", 1);
		pbJAI.setParameter("Kernel",   ((Number)jSpinnerKernel.getValue()).intValue());
		if (buttCon4.isSelected()) pbJAI.setParameter("Connectivety", 0);
		if (buttCon8.isSelected()) pbJAI.setParameter("Connectivety", 1);
		pbJAI.setParameter("ThresMin", ((Number)jSpinnerThresMin.getValue()).intValue());
		pbJAI.setParameter("ThresMax", ((Number)jSpinnerThresMax.getValue()).intValue());
		if (buttDam.isSelected())       pbJAI.setParameter("Output", 0);
		if (buttOverDam.isSelected())   pbJAI.setParameter("Output", 1);
		if (buttColBas.isSelected())    pbJAI.setParameter("Output", 2);
		if (buttComposite.isSelected()) pbJAI.setParameter("Output", 3);
		IqmTools.setCurrParameterBlockJAI(pbJAI);	
	}
	
	/**
	 * This method sets the current parameter values
	 *
	 */
	@Override
	public void setParameterValues(){
		int idx = IqmTools.getCurrManagerImgIndex();
	    PlanarImage pi = Tank.getCurrentTankImageAt(idx); 
	    if (pi == null){
	    	   System.out.println("IqmWatershedGUI: Current image not defined");
	    	   return;
	    }
	    
		if (pbJAI.getIntParameter("Invert")  == 0) jCheckBoxInvert.setSelected(false);
		if (pbJAI.getIntParameter("Invert")  == 1) jCheckBoxInvert.setSelected(true);

		if (pbJAI.getIntParameter("PreProc") == 0) buttNone.setSelected(true);
		if (pbJAI.getIntParameter("PreProc") == 1) buttGauss.setSelected(true);
       
	    jSpinnerKernel.removeChangeListener(this);	    	    
	    jSpinnerThresMin.removeChangeListener(this);	    	    
	    jSpinnerThresMax.removeChangeListener(this);	    	    
	    jSpinnerKernel.setValue(pbJAI.getIntParameter("Kernel"));
	    
		if (pbJAI.getIntParameter("Connectivety") == 0)  buttCon4.setSelected(true);
		if (pbJAI.getIntParameter("Connectivety") == 1)  buttCon8.setSelected(true);

	    jSpinnerThresMin.setValue(pbJAI.getIntParameter("ThresMin"));
	    jSpinnerThresMax.setValue(pbJAI.getIntParameter("ThresMax"));
	    jSpinnerKernel.addChangeListener(this);
	    jSpinnerThresMin.addChangeListener(this);
	    jSpinnerThresMax.addChangeListener(this);
	    
		if (pbJAI.getIntParameter("Output") == 0) buttDam.setSelected(true);
		if (pbJAI.getIntParameter("Output") == 1) buttOverDam.setSelected(true);
		if (pbJAI.getIntParameter("Output") == 2) buttColBas.setSelected(true);
		if (pbJAI.getIntParameter("Output") == 3) buttComposite.setSelected(true);
		
		if (buttGauss.isSelected()) {
			jSpinnerKernel.setEnabled(true);
	}else{
			jSpinnerKernel.setEnabled(false);
		}

	}

	/**
	 * This method creates and shows the GUI
	 */
	@Override
	public void createIqmOperatorGUI() {
		//System.out.println("IqmWatershed: createAndShowGUI invoked");
		//opGUIFrame = new IqmWatershedGUI();      //actionPerforemd events werden in dieser Klasse abgehandelt
		//opGUIFrame.getJContentPane();
		this.initialize(); //Aufruf von ImgProcFuncJFrame
		this.setTitle("Watershed");
		PlanarImage pi = Tank.getCurrentTankImageAt(IqmTools.getCurrManagerImgIndex());	
		
		//this.setSize(dim.width, dim.height+280);
		//this.setPreferredSize(new Dimension(800, 600));
		this.getJContentPane().add(getJCheckBoxInvert(),  getGridBagConstraintsInvert());	
		this.getJContentPane().add(getJToolBarPreProc(),  getGridBagConstraintsButtonPreProcGroup());
		this.getJContentPane().add(getJPanelKernel(),     getGridBagConstraintsKernel());
		this.getJContentPane().add(getJPanelConnectivety(),  getGridBagConstraintsConnectivety());
		this.getJContentPane().add(getJPanelThresMin(),   getGridBagConstraintsThresMin());
		this.getJContentPane().add(getJPanelThresMax(),   getGridBagConstraintsThresMax());
		this.getJContentPane().add(getJToolBarOutput(),   getGridBagConstraintsButtonOutputGroup());
		this.pack();
		//this.repaint();
		if (pbJAI == null) pbJAI = new ParameterBlockJAI("IqmWatershed");  //nur wenn das erste mal aufgerufen
		//pbJAI = new ParameterBlockJAI("iqmthreshold"); //immer der default Block
		IqmTools.setCurrParameterBlockJAI(pbJAI);
		this.setParameterValues();
	
	}
	private  GridBagConstraints getGridBagConstraintsInvert(){
		GridBagConstraints gridBagConstraintsInvert = new GridBagConstraints();
		gridBagConstraintsInvert.gridx = 1;
		gridBagConstraintsInvert.gridy = 5;
		gridBagConstraintsInvert.gridwidth = 2;
		//gridBagConstraintsInvert.anchor = GridBagConstraints.LINE_START;
		gridBagConstraintsInvert.insets = new Insets(10,0,0,0); //top left bottom right
		//gridBagConstraintsInvert.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsInvert;
	}
	private  GridBagConstraints getGridBagConstraintsButtonPreProcGroup(){
		GridBagConstraints gridBagConstraintsButtonPreProcGroup = new GridBagConstraints();
		gridBagConstraintsButtonPreProcGroup.gridx = 1;
		gridBagConstraintsButtonPreProcGroup.gridy = 6;
		gridBagConstraintsButtonPreProcGroup.gridwidth = 2;//?
		gridBagConstraintsButtonPreProcGroup.insets = new Insets(10,0,0,0);  //top left bottom right		
		//gridBagConstraintsButtonPreProcGroup.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsButtonPreProcGroup;
	}	
	private  GridBagConstraints getGridBagConstraintsKernel(){
		GridBagConstraints gridBagConstraintsKernel = new GridBagConstraints();
		gridBagConstraintsKernel.gridx = 2;
		gridBagConstraintsKernel.gridy = 6;
		gridBagConstraintsKernel.gridwidth = 2;//?
		gridBagConstraintsKernel.insets = new Insets(10,0,0,0);  //top left bottom right
		//gridBagConstraintsKernel.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsKernel;
	}
	private  GridBagConstraints getGridBagConstraintsConnectivety(){
		GridBagConstraints gridBagConstraintsButtonConnectivetyGroup = new GridBagConstraints();
		gridBagConstraintsButtonConnectivetyGroup.gridx = 1;
		gridBagConstraintsButtonConnectivetyGroup.gridy = 7;
		gridBagConstraintsButtonConnectivetyGroup.gridwidth = 3;//?
		gridBagConstraintsButtonConnectivetyGroup.insets = new Insets(10,0,0,0);  //top left bottom right
		//gridBagConstraintsButtonConnectivetyGroup.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsButtonConnectivetyGroup;
	}
	private  GridBagConstraints getGridBagConstraintsThresMin(){
		GridBagConstraints gridBagConstraintsThresMin = new GridBagConstraints();
		gridBagConstraintsThresMin.gridx = 1;
		gridBagConstraintsThresMin.gridy = 8;
		gridBagConstraintsThresMin.gridwidth = 1;//?
		gridBagConstraintsThresMin.insets = new Insets(20,0,0,0);  //top left bottom right
		//gridBagConstraintsThresMin.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsThresMin;
	}
	private  GridBagConstraints getGridBagConstraintsThresMax(){
		GridBagConstraints gridBagConstraintsThresMax = new GridBagConstraints();
		gridBagConstraintsThresMax.gridx = 2;
		gridBagConstraintsThresMax.gridy = 8;
		gridBagConstraintsThresMax.gridwidth = 2;//?
		gridBagConstraintsThresMax.insets = new Insets(20,20,0,0);  //top left bottom right
		//gridBagConstraintsThresMax.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsThresMax;
	}
	private  GridBagConstraints getGridBagConstraintsButtonOutputGroup(){
		GridBagConstraints gridBagConstraintsButtonOutputGroup = new GridBagConstraints();
		gridBagConstraintsButtonOutputGroup.gridx = 2;
		gridBagConstraintsButtonOutputGroup.gridy = 9 ;
		gridBagConstraintsButtonOutputGroup.gridwidth = 2;//?
		gridBagConstraintsButtonOutputGroup.insets = new Insets(10,0,20,0);  //top left bottom right		
		//gridBagConstraintsButtonOutputGroup.fill = GridBagConstraints.BOTH;
		return gridBagConstraintsButtonOutputGroup;
	}
	//------------------------------------------------------------------------------------------------------------------
	/**
	 * This method closes and destroys the GUI
	 * 
	 * @return void
	 */
//	public void destroyGUI() {
//		if (this != null){
//					
//			//this.closeAndDestroyGUI();
//			//resetVariables();
//			//folgendes geht auch!?
//			this.setVisible(false);
//			this.dispose();
//			//this = null;
//		}
//	}
	/**
	 * This method updates the GUI
	 * This method overrides IqmOperatorJFrame
	 */
	@Override
	public void updateIqmOperatorGUI(){
	
	}
	//-----------------------------------------------------------------------
	/**
	 * This method initializes jCheckBoxInvert	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private  JCheckBox getJCheckBoxInvert() {
		if (jCheckBoxInvert == null) {
			jCheckBoxInvert = new JCheckBox();
			jCheckBoxInvert.setText("Invert Input Image");
			jCheckBoxInvert.setToolTipText("inverts input image if necessary (the code searches for dark objects in bright background)");
			jCheckBoxInvert.addActionListener(this);			
			jCheckBoxInvert.setActionCommand("parameter");			
		}
		return jCheckBoxInvert;
	}
	//-----------------------------------------------------------------------
	/**
	 * This method initializes the Option: 
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtNone() {
		if (buttNone == null) {
			buttNone = new JRadioButtonMenuItem();
			buttNone.setText("None");
			buttNone.setToolTipText("no preprocessing");
			buttNone.addActionListener(this);
			buttNone.setActionCommand("parameter");
		}
		return buttNone;
	}
	/**
	 * This method initializes the Option: 
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtGauss() {
		if (buttGauss == null) {
			buttGauss  = new JRadioButtonMenuItem();
			buttGauss.setText("Gaussian Blur");
			buttGauss.setToolTipText("preprocess with gaussian blur");
			buttGauss.addActionListener(this);
			buttGauss.setActionCommand("parameter");
		}
		return buttGauss;
	}
	/**
	 * This method initializes the hidden option	
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtPreProcHidden() {
		//if (buttPreProcHidden == null) {
			buttPreProcHidden  = new JRadioButtonMenuItem();
			buttPreProcHidden .setText("Hidden");
			buttPreProcHidden.setVisible(false);
		//}
		return buttPreProcHidden;
	}
	/**
	 * This method initializes jJToolBarBar	
	 * 	
	 * @return javax.swing.JToolBar	
	 */
	private   JToolBar getJToolBarPreProc() {
//		if (jToolBarPreProc== null) {
			jToolBarPreProc = new JToolBar("Options");
			jToolBarPreProc.setOrientation(1); // 0 Horizontal 1 Vertical orientation
			jToolBarPreProc.add(getJRadioButtonMenuButtNone());
			jToolBarPreProc.add(getJRadioButtonMenuButtGauss());
			//jToolBarPreProc.addSeparator();
			this.setButtonGroupPreProc();	//Gruppieren der JRadioButtons
//		}
		return jToolBarPreProc;
	}
	private  void setButtonGroupPreProc() {
		//if (ButtonGroup buttGroup == null) {
			buttGroupPreProc = new ButtonGroup();
			buttGroupPreProc.add(buttNone);
			buttGroupPreProc.add(buttGauss);
			buttGroupPreProc.add(buttPreProcHidden);
	}

	

	//-----------------------------------------------------------------------
//	class IntNumberVerifier extends InputVerifier { //damit muss Eingabe richtig sein 
//		@Override
//		public boolean verify(JComponent input) {
//		   JFormattedTextField ftf = (JFormattedTextField)input;
//		   JFormattedTextField.AbstractFormatter formatter = ftf.getFormatter();
//		   if (formatter != null) {
//		      String text = ftf.getText();
//		  	  try {
//				   text = text.replace(",", ".");
//				   Integer.valueOf(text);
//				   //Float.valueOf(text);
//					return true;
//			  } catch (NumberFormatException e) {
//					return false;
//			  }	 
//		   }
//		   return true;
//		}
////		public boolean shouldYieldFocus(JComponent input) {
////		System.out.println("NumberVerifier  shouldYieldFocus");
////
////          return verify(input);
////    }
//	}

	/**
	 * This method initializes jJPanelKernel	
	 * 	
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanelKernel() {
		if (jPanelKernel == null) {
			jPanelKernel = new JPanel();
			jPanelKernel.setLayout(new BorderLayout());		
			jLabelKernel = new JLabel("Kernel: ");
			jLabelKernel.setToolTipText("kernel size");
			jLabelKernel.setPreferredSize(new Dimension(65, 22));
			jLabelKernel.setHorizontalAlignment(JLabel.RIGHT);
			SpinnerModel sModel = new SpinnerNumberModel(3, 3, Integer.MAX_VALUE, 2); //init, min, max, step
			jSpinnerKernel = new JSpinner(sModel);
			jSpinnerKernel.setPreferredSize(new Dimension(60, 22));
			jSpinnerKernel.addChangeListener(this);
			JSpinner.DefaultEditor defEditor = (JSpinner.DefaultEditor)jSpinnerKernel.getEditor()  ;
			JFormattedTextField ftf = defEditor.getTextField() ;
			InternationalFormatter intFormatter = (InternationalFormatter)ftf.getFormatter() ;
			DecimalFormat decimalFormat = (DecimalFormat)intFormatter.getFormat() ;
			decimalFormat.applyPattern("#");  //decimalFormat.applyPattern("#,##0.0")  ;		
			jPanelKernel.add(jLabelKernel,   BorderLayout.WEST);
			jPanelKernel.add(jSpinnerKernel, BorderLayout.CENTER);			
		}
		return jPanelKernel;
	}
	//-----------------------------------------------------------------------------------------
	/**
	 * This method initializes the Option:
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenubuttCon4() {
		//if (buttCon4 == null) {
			buttCon4  = new JRadioButtonMenuItem();
			buttCon4 .setText("4-connectivety");
			buttCon4 .setToolTipText("4-connectivety");
			buttCon4 .addActionListener(this);
			buttCon4.setActionCommand("parameter");
		//}
		return buttCon4;
	}
	/**
	 * This method initializes the Option:
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenubuttCon8() {
		//if (buttCon8 == null) {
			buttCon8  = new JRadioButtonMenuItem();
			buttCon8 .setText("8-connectivety");
			buttCon8 .setToolTipText("8-connectivety");
			buttCon8 .addActionListener(this);
			buttCon8.setActionCommand("parameter");
			buttCon8.setEnabled(true);
		//}
		return buttCon8;
	}
	/**
	 * This method initializes the hidden option	
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtConnectivetyHidden() {
		//if (buttConnectivetyHidden == null) {
			buttConnectivetyHidden  = new JRadioButtonMenuItem();
			buttConnectivetyHidden .setText("Hidden");
			buttConnectivetyHidden.setVisible(false);
		//}
		return buttConnectivetyHidden;
	}
	/**
	 * This method initializes jJToolBarBar	
	 * 	
	 * @return javax.swing.JToolBar	
	 */
	private JPanel getJPanelConnectivety() {
//		if (jToolBarConnectivety== null) {
			jPanelConnectivety = new JPanel();
			jPanelConnectivety.setLayout(new BorderLayout());	
			jLabelConnectivety = new JLabel("  Connectivety");
			jToolBarConnectivety = new JToolBar("Options");
			jToolBarConnectivety.setOrientation(1); // 0 Horizontal 1 Vertical orientation
			jToolBarConnectivety.add(getJRadioButtonMenubuttCon4());
			jToolBarConnectivety.add(getJRadioButtonMenubuttCon8());
			jToolBarConnectivety.add(getJRadioButtonMenuButtConnectivetyHidden());
			//jToolBarConnectivety.addSeparator();
			this.setButtonGroupConnectivety();	//Gruppieren der JRadioButtons
			jPanelConnectivety.add(jToolBarConnectivety, BorderLayout.WEST);	
			jPanelConnectivety.add(jLabelConnectivety, 	 BorderLayout.CENTER);

//		}
		return jPanelConnectivety;
	}
	private void setButtonGroupConnectivety() {
		//if (ButtonGroup buttGroup == null) {
			buttGroupConnectivety = new ButtonGroup();
			buttGroupConnectivety.add(buttCon4);
			buttGroupConnectivety.add(buttCon8);
			buttGroupConnectivety.add(buttConnectivetyHidden);
	}
	//-----------------------------------------------------------------------------------------
	/**
	 * This method initializes jJPanelThresMin	
	 * 	
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanelThresMin() {
		if (jPanelThresMin == null) {
			jPanelThresMin = new JPanel();
			jPanelThresMin.setLayout(new BorderLayout());		
			jLabelThresMin = new JLabel("Thres Min: ");
			jLabelThresMin.setToolTipText("threshold minimum");
			jLabelThresMin.setPreferredSize(new Dimension(70, 22));
			jLabelThresMin.setHorizontalAlignment(JLabel.RIGHT);
			SpinnerModel sModel = new SpinnerNumberModel(0, 0, 255, 1); //init, min, max, step
			jSpinnerThresMin = new JSpinner(sModel);
			jSpinnerThresMin.setPreferredSize(new Dimension(60, 22));
			jSpinnerThresMin.addChangeListener(this);
			JSpinner.DefaultEditor defEditor = (JSpinner.DefaultEditor)jSpinnerThresMin.getEditor()  ;
			JFormattedTextField ftf = defEditor.getTextField() ;
			jFormattedTextFieldThresMin = ftf;
			InternationalFormatter intFormatter = (InternationalFormatter)ftf.getFormatter() ;
			DecimalFormat decimalFormat = (DecimalFormat)intFormatter.getFormat() ;
			decimalFormat.applyPattern("#");  //decimalFormat.applyPattern("#,##0.0")  ;		
			jPanelThresMin.add(jLabelThresMin, 	 BorderLayout.WEST);
			jPanelThresMin.add(jSpinnerThresMin, BorderLayout.CENTER);			
		}
		return jPanelThresMin;
	}
	/**
	 * This method initializes jJPanelThresMax	
	 * 	
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanelThresMax() {
		if (jPanelThresMax == null) {
			jPanelThresMax = new JPanel();
			jPanelThresMax.setLayout(new BorderLayout());		
			jLabelThresMax = new JLabel("Thres Max: ");
			jLabelThresMax.setToolTipText("threshold maximum"); 
			jLabelThresMax.setHorizontalAlignment(JLabel.RIGHT);
			jLabelThresMax.setPreferredSize(new Dimension(70, 22));
			SpinnerModel sModel = new SpinnerNumberModel(255, 0, 255, 1); //init, min, max, step
			jSpinnerThresMax = new JSpinner(sModel);
			jSpinnerThresMax.setPreferredSize(new Dimension(60, 22));
			jSpinnerThresMax.addChangeListener(this);
			JSpinner.DefaultEditor defEditor = (JSpinner.DefaultEditor)jSpinnerThresMax.getEditor()  ;
			JFormattedTextField ftf = defEditor.getTextField() ;
			jFormattedTextFieldThresMax = ftf;
			InternationalFormatter intFormatter = (InternationalFormatter)ftf.getFormatter() ;
			DecimalFormat decimalFormat = (DecimalFormat)intFormatter.getFormat() ;
			decimalFormat.applyPattern("#");  //decimalFormat.applyPattern("#,##0.0")  ;		
			jPanelThresMax.add(jLabelThresMax, 	 BorderLayout.WEST);
			jPanelThresMax.add(jSpinnerThresMax, BorderLayout.CENTER);			
		}
		return jPanelThresMax;
	}
	

	//--------------------------------------------------------------------------------------------

	/**
	 * This method initializes the Option: 
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtDam() {
		if (buttDam == null) {
			buttDam = new JRadioButtonMenuItem();
			buttDam.setText("Dams");
			buttDam.setToolTipText("output: dams");
			buttDam.addActionListener(this);
			buttDam.setActionCommand("parameter");
		}
		return buttDam;
	}
	/**
	 * This method initializes the Option: 
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtOverDam() {
		//if (buttOverDam == null) {
			buttOverDam  = new JRadioButtonMenuItem();
			buttOverDam.setText("Overlaid Dams");
			buttOverDam.setToolTipText("output: overlaid dams");
			buttOverDam.addActionListener(this);
			buttOverDam.setActionCommand("parameter");
		//}
		return buttOverDam;
	}
	/**
	 * This method initializes the Option: 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtColBas() {
		//if (buttColBas == null) {
			buttColBas = new JRadioButtonMenuItem();
			buttColBas.setText("Colorized Basins");
			buttColBas.setToolTipText("output: colorized basins");
			buttColBas.addActionListener(this);
			buttColBas.setActionCommand("parameter");
		//}
		return buttColBas;
	}
	/**
	 * This method initializes the Option: 
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtComposite() {
		//if (buttComposite == null) {
			buttComposite = new JRadioButtonMenuItem();
			buttComposite.setText("Composite");
			buttComposite.setToolTipText("output: composite");
			buttComposite.addActionListener(this);
			buttComposite.setActionCommand("parameter");
		//}
		return buttComposite;
	}
	/**
	 * This method initializes the hidden option	
	 * 	
	 * @return javax.swing.JRadioButtonMenuItem	
	 */
	private  JRadioButtonMenuItem getJRadioButtonMenuButtOutputHidden() {
		//if (buttOutputHidden == null) {
			buttOutputHidden = new JRadioButtonMenuItem();
			buttOutputHidden.setText("Hidden");
			buttOutputHidden.setVisible(false);
		//}
		return buttOutputHidden;
	}
	/**
	 * This method initializes jJToolBarBar	
	 * 	
	 * @return javax.swing.JToolBar	
	 */
	private   JToolBar getJToolBarOutput() {
//		if (jToolBarOutput== null) {
			jToolBarOutput = new JToolBar("Options");
			jToolBarOutput.setOrientation(1); // 0 Horizontal 1 Vertical orientation
			jToolBarOutput.add(getJRadioButtonMenuButtDam());
			jToolBarOutput.add(getJRadioButtonMenuButtOverDam());
			jToolBarOutput.add(getJRadioButtonMenuButtColBas());
			jToolBarOutput.add(getJRadioButtonMenuButtComposite());
			jToolBarOutput.add(getJRadioButtonMenuButtOutputHidden());
			//jToolBarOutput.addSeparator();
			this.setButtonGroupOutput();	//Gruppieren der JRadioButtons
//		}
		return jToolBarOutput;
	}
	private  void setButtonGroupOutput() {
		//if (ButtonGroup buttGroup == null) {
			buttGroupOutput = new ButtonGroup();
			buttGroupOutput.add(buttDam);
			buttGroupOutput.add(buttOverDam);
			buttGroupOutput.add(buttColBas);
			buttGroupOutput.add(buttComposite);
			buttGroupOutput.add(buttOutputHidden);
	}

	//--------------------------------------------------------------------------------------------
	public void actionPerformed(ActionEvent e) {
		//System.out.println("IqmWatershedGUI: event e: " +e.getActionCommand());
		if ("reset".equals(e.getActionCommand())) {
			ParameterBlockJAI pbJAI = new ParameterBlockJAI("IqmWatershed".toLowerCase());
			IqmTools.setCurrParameterBlockJAI(pbJAI);
			this.setParameterBlock(pbJAI);
			this.setParameterValues();
			//this.updateIqmOperatorGUI();  //if necessary here or some lines above
			this.reset();
		}
		if ("parameter".equals(e.getActionCommand())) {

			if (buttNone == e.getSource()){
			}
			if (buttGauss == e.getSource()) {
			}

			if (buttGauss.isSelected()) {
				jSpinnerKernel.setEnabled(true);
			}else{
				jSpinnerKernel.setEnabled(false);
			}	
			this.setParameterBlock();
			//this.updateIqmOperatorGUI();  //if necessary here or some lines above
		}
	
		//preview if selected
		if (this.isAutoPreviewSelected()){
			this.showPreview();
		}

	}
	//-----------------------------------------------------------------------------------------------

	@Override
	public void propertyChange(PropertyChangeEvent e) {
		int kernelSize  = ((Number)jSpinnerKernel.getValue()).intValue();
		int thresMin    = ((Number)jSpinnerThresMin.getValue()).intValue();
		int thresMax    = ((Number)jSpinnerThresMax.getValue()).intValue();

		this.setParameterBlock();
		//this.updateIqmOperatorGUI();  //if necessary here or some lines above
		
		//preview if selected
		if (this.isAutoPreviewSelected()){
			this.showPreview();
		}
	}
	//-------------------------------------------------------------------------------------------------
	@Override
	public void stateChanged(ChangeEvent e) {
		
		int kernelSize  = ((Number)jSpinnerKernel.getValue()).intValue();
		int thresMin    = ((Number)jSpinnerThresMin.getValue()).intValue();
		int thresMax    = ((Number)jSpinnerThresMax.getValue()).intValue();
		
		if (jSpinnerKernel  == e.getSource()) {
			if (kernelSize%2 == 0){//even;
			    jSpinnerKernel.removeChangeListener(this);	    	    
				jSpinnerKernel.setValue(kernelSize+1);
			    jSpinnerKernel.addChangeListener(this);	    	    

			}
			if (kernelSize%2 != 0){//odd;
			}

		}
		if (jSpinnerThresMin  == e.getSource()) {
			if (thresMin >= thresMax){
			    jSpinnerThresMin.removeChangeListener(this);	    	    
				jSpinnerThresMin.setValue(thresMax-1);
			    jSpinnerThresMin.addChangeListener(this);	    	    

			}
		}
		if (jSpinnerThresMax  == e.getSource()) {
			if (thresMax <= thresMin){
			    jSpinnerThresMax.removeChangeListener(this);	    	    
				jSpinnerThresMax.setValue(thresMin+1);
			    jSpinnerThresMax.addChangeListener(this);	    	    

			}
		}
		this.setParameterBlock();
		//this.updateIqmOperatorGUI();  //if necessary here or some lines above
		
		//preview if selected
		if (this.isAutoPreviewSelected()){
			this.showPreview();
		}
		
	}


	//-------------------------------------------------------------------------------------------------
	public static void main() {

		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				IqmWatershedGUI gui = new IqmWatershedGUI();
				gui.createIqmOperatorGUI();

			}
		});
	}
	
}//END
